package com.elysia.blogspringboot.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.elysia.blogspringboot.domain.entity.Resource;
import com.elysia.blogspringboot.domain.vo.ResourceVo;
import com.elysia.blogspringboot.enumeration.UploadFileEnum;
import com.elysia.blogspringboot.mapper.ResourceMapper;
import com.elysia.blogspringboot.service.IResourceService;
import com.elysia.blogspringboot.untils.AliyunOssUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@RequiredArgsConstructor
@Service
@Slf4j
public class IResourceServiceImpl extends ServiceImpl<ResourceMapper, Resource> implements IResourceService {
    private final IUserServiceImpl userService;
    private final ObjectMapper objectMapper;
    private final AliyunOssUtils ossUtils;
    @Override
    public List<ResourceVo> getFileList() throws JsonProcessingException {
        List<ResourceVo> resourceVoList = new ArrayList<>();
        List<Resource> resources = list();
        for (Resource resource : resources){
            resourceVoList.add(ResourceVo.builder()
                    .id(resource.getId())
                    .name(resource.getName())
                    .fileName(resource.getFileName())
                    .description(resource.getDescription())
                    .version(resource.getVersion())
                    .size(formatFileSize(Long.parseLong(resource.getSize())))
                    .downloads(resource.getDownloads())
                    .updateDate(resource.getUpdateDate())
                    .category(resource.getCategory())
                    .features(objectMapper.readValue(resource.getFeatures(), new TypeReference<>() {}))
                    .uploader(userService.getById(resource.getUploader()).getUsername()).build()
            );
        }
        return resourceVoList;
    }

    @Override
    public boolean saveResourceInformation(Resource resource, byte[] bytes) {
        Resource existingResource = lambdaQuery()
                .eq(Resource::getFileName, resource.getFileName())
                .eq(Resource::getVersion, resource.getVersion())
                .one();
        // 如果已存在，直接返回
        if (existingResource != null) return false;
        String category = resource.getCategory();
        UploadFileEnum uploadFileEnum;
        switch (category){
            case "mod" -> uploadFileEnum = UploadFileEnum.MOD;
            case "client" -> uploadFileEnum = UploadFileEnum.CLIENT;
            default -> uploadFileEnum = UploadFileEnum.RESOURCE;
        }
        String suffix = resource.getFileName().substring(resource.getFileName().lastIndexOf("."));
        ossUtils.upload(bytes, resource.getName() + resource.getVersion() + category + suffix, uploadFileEnum);
        return save(resource);
    }
    /**
     * 智能转换文件大小单位
     * @param bytes 文件大小（字节）
     * @return 转换后的带单位的文件大小字符串
     */
    public static String formatFileSize(long bytes) {
        // 定义单位数组
        String[] units = {"B", "KB", "MB", "GB"};

        // 如果字节数为0，直接返回0B
        if (bytes == 0) {
            return "0 " + units[0];
        }

        // 计算最合适的单位索引
        int unitIndex = (int) (Math.log10(bytes) / Math.log10(1024));
        // 确保单位索引不超过最大单位
        unitIndex = Math.min(unitIndex, units.length - 1);

        // 计算转换后的大小
        double size = bytes / Math.pow(1024, unitIndex);

        // 格式化输出，保留两位小数并添加单位
        return String.format("%.2f %s", size, units[unitIndex]);
    }
}
